﻿using System;
using System.Web.Mvc;
using System.Web.MVC;
using System.Web.Security;
using AutoMapper;
using NTQOnlineExam.Services.CommandService;
using NTQOnlineExam.Services.CommandService.Baskets;
using NTQOnlineExam.Services.CommandService.Orders;
using NTQOnlineExam.Services.CommandService.Payment;
using NTQOnlineExam.Services.Infrastructure.Utility;
using NTQOnlineExam.Services.Models;
using NTQOnlineExam.Services.ReportService.Account;
using NTQOnlineExam.Services.ReportService.Basket;
using NTQOnlineExam.Services.ReportService.Order;
using NTQOnlineExamFrontend.Models;

namespace NTQOnlineExamFrontend.Controllers
{
    [Authorize]
    public class BasketController : Controller
    {
        private readonly IAccountReportService _accountReportService;
        private readonly IBasketCommandService _basketCommandService;
        private readonly IBasketReportService _basketReportService;
        private readonly IOrderReportService _orderReportService;
        public BasketController(IBasketCommandService basketCommandService, IBasketReportService basketReportService, IAccountReportService accountReportService, IOrderReportService orderReportService)
        {
            _basketCommandService = basketCommandService;
            _basketReportService = basketReportService;
            _accountReportService = accountReportService;
            _orderReportService = orderReportService;
        }

        [HttpGet]
        public ActionResult GetUserBasket()
        {
            var basketDTO = _basketReportService.GetShoppingBasketByUserName(_accountReportService.GetCurrentUser().UserName);
            var model = Mapper.Map<BasketDTO, BasketViewModel>(basketDTO) ?? new BasketViewModel();
            if (!Request.IsAjaxRequest())
            {

                return View("Basket", model);
            }
            else
            {
                return PartialView("_TopBasket", model);
            }
        }

        [HttpGet]
        public ActionResult GetTopUserBasket()
        {
            var basketDTO = _basketReportService.GetShoppingBasketByUserName(_accountReportService.GetCurrentUser().UserName);
            var model = Mapper.Map<BasketDTO, BasketViewModel>(basketDTO) ?? new BasketViewModel();
            return View("Basket", model);
        }


        [HttpGet]
        public ActionResult Checkout()
        {

            var currentUser = _accountReportService.GetByUserName(_accountReportService.GetCurrentUser().UserName);
            var basketDTO = _basketReportService.GetShoppingBasketByUserName(currentUser.UserName);
            var checkoutViewModel = Mapper.Map<UserProfileDTO, CheckoutViewModel>(currentUser) ??
                                    new CheckoutViewModel();
            checkoutViewModel.CanCheckout = basketDTO.BasketItems != null && basketDTO.BasketItems.Count > 0;
            return View(checkoutViewModel);
        }

        [HttpPost]
        public ActionResult AddToBasket(int termId)
        {
            try
            {
                if (termId > 0)
                {
                    string message;
                    _basketCommandService.AddTerm(termId, string.Empty, out message);
                    if (!string.IsNullOrEmpty(message))
                    {
                        ModelState.AddModelError("Add to Basket", message);
                        return ModelState.JsonValidation();
                    }
                    var basketDTO = _basketReportService.GetShoppingBasketByUserName(_accountReportService.GetCurrentUser().UserName);
                    return ModelState.JsonValidation(new { Success = true, basketDTO.BasketId, basketDTO.BasketItems.Count });
                }
            }
            catch (Exception ex)
            {
                ModelState.AddModelError("AddToBasket", ex.Message);
            }
            return ModelState.JsonValidation();
        }

        [HttpPost]
        public ActionResult RemoveBasketItem(string id)
        {
            try
            {
                Guid itemId = ValueUtilities.GetGuid(id, Guid.Empty);
                if (!itemId.Equals(Guid.Empty))
                {
                    _basketCommandService.RemoveBasketItem(itemId);
                    var basketDTO = _basketReportService.GetShoppingBasketByUserName(_accountReportService.GetCurrentUser().UserName);
                    return ModelState.JsonValidation(new { Success = true, basketDTO.BasketId, basketDTO.BasketItems.Count, TotalPrice = basketDTO.GetTotalPrice().ToString("##,### AUD") });
                }
            }
            catch (Exception ex)
            {
                ModelState.AddModelError("Remove", ex.Message);
            }
            return ModelState.JsonValidation();
        }

        [HttpPost]
        public ActionResult Checkout(CheckoutViewModel model)
        {
            if (ModelState.IsValid)
            {
                try
                {
                    string message;
                    var result = _basketCommandService.Checkout(new CheckoutCommand()
                    {
                        BillingAddress = model.BillingAddress,
                        BillingCity = model.BillingCity,
                        BillingZipCode = model.BillingZipCode,
                        BillingCountry = model.BillingCountry,
                        BillingPOBox = model.BillingPOBox,
                        Email = model.Email,
                        FirstName = model.FirstName,
                        LastName = model.LastName
                    }, out message);

                    if (result) return Redirect(message);
                    ModelState.AddModelError("", message);
                }
                catch (Exception ex)
                {
                    ModelState.AddModelError("", ex.Message);
                }

            }
            return View(model);
        }

        public ActionResult OrderConfirmation(string orderId)
        {
            Guid temp = Guid.Empty;
            Guid.TryParse(orderId, out temp);
            var order = _orderReportService.GetOrderById(temp);
            return View(new OrderConfirmationViewModel() { Order = order });
        }
    }
}
